package com.video.moderation.filter;

import com.video.moderation.constant.SecurityConstants;
import com.video.moderation.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class JwtAuthFilter extends OncePerRequestFilter {

    @Resource
    private JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal
            (HttpServletRequest request,
             HttpServletResponse response,
             FilterChain filterChain)
            throws ServletException, IOException {
        String token = request.getHeader(SecurityConstants.AUTHORIZATION);
        
        if (token == null || token.isEmpty()) {
            filterChain.doFilter(request, response);
            return;
        }
        
        Claims claims = jwtUtils.getClaims(token);
        if (claims == null) throw new ServletException("token令牌无效");
        
        if (jwtUtils.isExpire(claims.getExpiration())) throw new ServletException("token令牌过期");

        String memberNum = (String) claims.get(SecurityConstants.MEMBER_NUM);
        Integer memberId = (Integer) claims.get(SecurityConstants.MEMBER_ID);
        
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("超级管理员"));
        authorities.add(new SimpleGrantedAuthority("客服审核员"));
        authorities.add(new SimpleGrantedAuthority("普通管理员"));
        
        // 这里提供的Token是正确的，因此不需要设置密码。实现自动登录。
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(memberNum, null, authorities);
        authenticationToken.setDetails(memberId);
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        
        filterChain.doFilter(request, response);
    }

}
